﻿using Canteen.Core.Services;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using Canteen.Core.Models;

namespace Canteen.Core.WebApp.API.Controllers
{
    [Route("wechat")]
    [ApiController]
    public class WechatController : ControllerBase
    {
        #region 构造函数
        private readonly IWechatService wechatService;
        public WechatController(IWechatService wechatService)
        {
            this.wechatService = wechatService ?? throw new ArgumentNullException(nameof(wechatService));
        }
        #endregion

        #region 内部函数        
        private string SHAEncryption(string str)
        {
            //创建SHA1加密算法对象
            SHA1 sha1 = SHA1.Create();
            //将原始密码转换为字节数组
            byte[] originalPwd = Encoding.UTF8.GetBytes(str);
            //执行加密
            byte[] encryPwd = sha1.ComputeHash(originalPwd);
            //将加密后的字节数组转换为大写字符串
            return string.Join("", encryPwd.Select(b => string.Format("{0:x2}", b)).ToArray());
        }
        /// <summary>
        /// 签名算法
        ///本代码来自开源微信SDK项目：https://github.com/night-king/weixinSDK
        /// </summary>
        /// <param name="jsapi_ticket">jsapi_ticket</param>
        /// <param name="noncestr">随机字符串(必须与wx.config中的nonceStr相同)</param>
        /// <param name="timestamp">时间戳(必须与wx.config中的timestamp相同)</param>
        /// <param name="url">当前网页的URL，不包含#及其后面部分(必须是调用JS接口页面的完整URL)</param>
        /// <returns></returns>
        private string GetSignature(string jsapi_ticket, string nonceStr, long timestamp, string url)
        {
            var string1Builder = new StringBuilder();
            string1Builder.Append("jsapi_ticket=").Append(jsapi_ticket).Append("&")
                          .Append("noncestr=").Append(nonceStr).Append("&")
                          .Append("timestamp=").Append(timestamp).Append("&")
                          .Append("url=").Append(url.IndexOf("#") >= 0 ? url.Substring(0, url.IndexOf("#")) : url);
            return SHAEncryption(string1Builder.ToString());
        }
        #endregion

        #region JS-SDK使用权限签名算法
        // GET /wechat/sign
        [HttpGet("Sign")]
        public async Task<IActionResult> JSAPISign([FromQuery] string url)
        {
            if (string.IsNullOrWhiteSpace(url)) throw new ArgumentNullException(nameof(url));
            string jsapi_ticket = await wechatService.GetJSAPITicket();
            string nonceStr = Guid.NewGuid().ToString().Replace("-", "");
            long timestamp = Convert.ToInt64((DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalMilliseconds);
            string signature = GetSignature(jsapi_ticket, nonceStr, timestamp, WebUtility.UrlDecode(url));
            return Ok(HttpResult<object>.Success(new { appId = wechatService.Options.AppID, timestamp, nonceStr, signature }));
        }
        #endregion
    }
}
